From 900a11e8ed5635cf98d5dbad7d8a5d12fba9479c Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sat, 22 Oct 2005 08:35:03 +0100 Subject: [PATCH] cpumap cleanups -- Python now deals with lists of cpus rather than cpu bitmaps. Signed-off-by: Ryan Harper Signed-off-by: Keir Fraser --- tools/python/xen/lowlevel/xc/xc.c | 36 +++++++++---- tools/python/xen/xend/XendClient.py | 2 +- tools/python/xen/xend/XendDomain.py | 5 +- tools/python/xen/xend/XendDomainInfo.py | 6 ++- tools/python/xen/xend/server/SrvDomain.py | 2 +- tools/python/xen/xm/main.py | 66 ++++++++++++++++++++--- 6 files changed, 97 insertions(+), 20 deletions(-) diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index e4855158b6..e3c2dbcb36 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -204,15 +204,23 @@ static PyObject *pyxc_domain_pincpu(PyObject *self, XcObject *xc = (XcObject *)self; uint32_t dom; - int vcpu = 0; + int vcpu = 0, i; cpumap_t cpumap = ~0ULL; + PyObject *cpulist = NULL; static char *kwd_list[] = { "dom", "vcpu", "cpumap", NULL }; - if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|ii", kwd_list, - &dom, &vcpu, &cpumap) ) + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|iO", kwd_list, + &dom, &vcpu, &cpulist) ) return NULL; + if ( (cpulist != NULL) && PyList_Check(cpulist) ) + { + cpumap = 0ULL; + for ( i = 0; i < PyList_Size(cpulist); i++ ) + cpumap |= (cpumap_t)1 << PyInt_AsLong(PyList_GetItem(cpulist, i)); + } + if ( xc_domain_pincpu(xc->xc_handle, dom, vcpu, cpumap) != 0 ) return PyErr_SetFromErrno(xc_error); @@ -347,11 +355,12 @@ static PyObject *pyxc_vcpu_getinfo(PyObject *self, PyObject *kwds) { XcObject *xc = (XcObject *)self; - PyObject *info_dict; + PyObject *info_dict, *cpulist; uint32_t dom, vcpu = 0; xc_vcpuinfo_t info; - int rc; + int rc, i; + cpumap_t cpumap; static char *kwd_list[] = { "dom", "vcpu", NULL }; @@ -363,13 +372,22 @@ static PyObject *pyxc_vcpu_getinfo(PyObject *self, if ( rc < 0 ) return PyErr_SetFromErrno(xc_error); - info_dict = Py_BuildValue("{s:i,s:i,s:i,s:L,s:i,s:i}", + info_dict = Py_BuildValue("{s:i,s:i,s:i,s:L,s:i}", "online", info.online, "blocked", info.blocked, "running", info.running, "cpu_time", info.cpu_time, - "cpu", info.cpu, - "cpumap", info.cpumap); + "cpu", info.cpu); + + cpumap = info.cpumap; + cpulist = PyList_New(0); + for ( i = 0; cpumap != 0; i++ ) + { + if ( cpumap & 1 ) + PyList_Append(cpulist, PyInt_FromLong(i)); + cpumap >>= 1; + } + PyDict_SetItemString(info_dict, "cpumap", cpulist); return info_dict; } @@ -896,7 +914,7 @@ static PyMethodDef pyxc_methods[] = { "Pin a VCPU to a specified set CPUs.\n" " dom [int]: Identifier of domain to which VCPU belongs.\n" " vcpu [int, 0]: VCPU being pinned.\n" - " cpumap [int, -1]: Bitmap of usable CPUs.\n\n" + " cpumap [list, []]: list of usable CPUs.\n\n" "Returns: [int] 0 on success; -1 on error.\n" }, { "domain_setcpuweight", diff --git a/tools/python/xen/xend/XendClient.py b/tools/python/xen/xend/XendClient.py index 9fe93bab99..9cbef2401b 100644 --- a/tools/python/xen/xend/XendClient.py +++ b/tools/python/xen/xend/XendClient.py @@ -258,7 +258,7 @@ class Xend: return self.xendPost(self.domainurl(id), {'op' : 'pincpu', 'vcpu' : vcpu, - 'cpumap' : cpumap }) + 'cpumap' : str(cpumap) }) def xend_domain_cpu_bvt_set(self, id, mcuadv, warpback, warpvalue, warpl, warpu): return self.xendPost(self.domainurl(id), diff --git a/tools/python/xen/xend/XendDomain.py b/tools/python/xen/xend/XendDomain.py index 0b50c83b55..3c0532645c 100644 --- a/tools/python/xen/xend/XendDomain.py +++ b/tools/python/xen/xend/XendDomain.py @@ -412,9 +412,12 @@ class XendDomain: def domain_pincpu(self, domid, vcpu, cpumap): """Set which cpus vcpu can use - @param cpumap: bitmap of usable cpus + @param cpumap: string repr of list of usable cpus """ dominfo = self.domain_lookup(domid) + # convert cpumap string into a list of ints + cpumap = map(lambda x: int(x), + cpumap.replace("[", "").replace("]", "").split(",")) try: return xc.domain_pincpu(dominfo.getDomid(), vcpu, cpumap) except Exception, ex: diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index bb34abd099..061e7863d5 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -980,6 +980,9 @@ class XendDomainInfo: def getVCPUInfo(self): try: + def filter_cpumap(map, max): + return filter(lambda x: x >= 0, map[0:max]) + # We include the domain name and ID, to help xm. sxpr = ['domain', ['domid', self.domid], @@ -996,7 +999,8 @@ class XendDomainInfo: ['running', info['running']], ['cpu_time', info['cpu_time'] / 1e9], ['cpu', info['cpu']], - ['cpumap', info['cpumap']]]) + ['cpumap', filter_cpumap(info['cpumap'], + self.info['vcpus'])]]) return sxpr diff --git a/tools/python/xen/xend/server/SrvDomain.py b/tools/python/xen/xend/server/SrvDomain.py index 40ddc81972..676c5f37ca 100644 --- a/tools/python/xen/xend/server/SrvDomain.py +++ b/tools/python/xen/xend/server/SrvDomain.py @@ -89,7 +89,7 @@ class SrvDomain(SrvDir): fn = FormFn(self.xd.domain_pincpu, [['dom', 'int'], ['vcpu', 'int'], - ['cpumap', 'int']]) + ['cpumap', 'str']]) val = fn(req.args, {'dom': self.dom.domid}) return val diff --git a/tools/python/xen/xm/main.py b/tools/python/xen/xm/main.py index 7e35899fc0..f9771f6c0a 100644 --- a/tools/python/xen/xm/main.py +++ b/tools/python/xen/xm/main.py @@ -289,6 +289,62 @@ def xm_vcpu_list(args): def get_info(n): return sxp.child_value(dom, n) + # + # convert a list of integers into a list of pairs indicating + # continuous sequences in the list: + # + # [0,1,2,3] -> [(0,3)] + # [1,2,4,5] -> [(1,2),(4,5)] + # [0] -> [(0,0)] + # [0,1,4,6,7] -> [(0,1),(4,4),(6,7)] + # + def list_to_rangepairs(cmap): + cmap.sort() + pairs = [] + x = y = 0 + for i in range(0,len(cmap)): + try: + if ((cmap[y+1] - cmap[i]) > 1): + pairs.append((cmap[x],cmap[y])) + x = y = i+1 + else: + y = y + 1 + # if we go off the end, then just add x to y + except IndexError: + pairs.append((cmap[x],cmap[y])) + + return pairs + + # + # Convert pairs to range string, e.g: [(1,2),(3,3),(5,7)] -> 1-2,3,5-7 + # + def format_pairs(pairs): + out = "" + for f,s in pairs: + if (f==s): + out += '%d'%f + else: + out += '%d-%d'%(f,s) + out += ',' + # trim trailing ',' + return out[:-1] + + def format_cpumap(cpumap): + def uniq(x): + return [ u for u in x if u not in locals()['_[1]'] ] + + from xen.xend.XendClient import server + for x in server.xend_node()[1:]: + if len(x) > 1 and x[0] == 'nr_cpus': + nr_cpus = int(x[1]) + break + + return format_pairs( + list_to_rangepairs( + map(lambda x: x % nr_cpus, + uniq(map(lambda x: int(x), cpumap)) ))) + + name = get_info('name') domid = int(get_info('domid')) @@ -299,7 +355,7 @@ def xm_vcpu_list(args): number = vinfo('number', int) cpu = vinfo('cpu', int) - cpumap = vinfo('cpumap', int) + cpumap = format_cpumap(vinfo('cpumap', list)) online = vinfo('online', int) cpu_time = vinfo('cpu_time', float) running = vinfo('running', int) @@ -321,7 +377,7 @@ def xm_vcpu_list(args): s = "--p" print ( - "%(name)-32s %(domid)3d %(number)4d %(c)3s %(s)-3s %(cpu_time)7.1f 0x%(cpumap)x" % + "%(name)-32s %(domid)3d %(number)4d %(c)3s %(s)-3s %(cpu_time)7.1f %(cpumap)s" % locals()) @@ -355,7 +411,6 @@ def xm_subcommand(command, args): def cpu_make_map(cpulist): cpus = [] - cpumap = 0 for c in cpulist.split(','): if c.find('-') != -1: (x,y) = c.split('-') @@ -364,10 +419,7 @@ def cpu_make_map(cpulist): else: cpus.append(int(c)) cpus.sort() - for c in cpus: - cpumap = cpumap | 1<